/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
module dwt.dnd.dnd;


private import dwt.dwt;
private import dwt.internal.converter;
private import dwt.util.util;


/**
 *
 * Class DND contains all the constants used in defining a 
 * DragSource or a DropTarget.
 *
 */
public class DND {


	private import std.c.windows.windows;

	/**
	 * The transfer mechanism for data that is being cut
	 * and then pasted or copied and then pasted (value is 1).
	 * 
	 * @see Clipboard
	 * 
	 * @since 3.1
	 */
	public const static int CLIPBOARD = 1 << 0;
	
	/**
	 * The transfer mechanism for clients that use the selection 
	 * mechanism (value is 2).
	 * 
	 * @see Clipboard
	 *
	 * @since 3.1
	 */
	public const static int SELECTION_CLIPBOARD = 1 << 1;

	
	/**
	 * Drag and Drop Operation: no drag/drop operation performed
	 * (value is 0).
	 */
	public static const int DROP_NONE = 0;
	
	/**
	 * Drag and Drop Operation: a copy of the data in the drag source is 
	 * added to the drop target (value is 1 &lt;&lt; 0).
	 */
	public static const int DROP_COPY = 1 << 0;
	
	/**
	 * Drag and Drop Operation: a copy of the data is added to the drop target and 
	 * the original data is removed from the drag source (value is 1 &lt;&lt; 1).
	 */
	public static const int DROP_MOVE = 1 << 1;
	
	/**
	 * Drag and Drop Operation: the drop target makes a link to the data in 
	 * the drag source (value is 1 &lt;&lt; 2).
	 */
	public static const int DROP_LINK = 1 << 2;
	
	/**
	 * Drag and Drop Operation: the drop target moves the data and the drag source removes 
	 * any references to the data and updates its display.  This is not available on all platforms
	 * and is only used when a non-DWT application is the drop target.  In this case, the DWT 
	 * drag source is informed in the dragFinished event that the drop target has moved the data.
	 * (value is 1 &lt;&lt; 3).
	 * 
	 * @see DragSourceListener#dragFinished
	 */
	public static const int DROP_TARGET_MOVE = 1 << 3;
	
	/**
	 * Drag and Drop Operation: During a dragEnter event or a dragOperationChanged, if no modifier keys
	 * are pressed, the operation is set to DROP_DEFAULT.  The application can choose what the default 
	 * operation should be by setting a new value in the operation field.  If no value is choosen, the
	 * default operation for the platform will be selected (value is 1 &lt;&lt; 4).
	 * 
	 * @see DropTargetListener#dragEnter
	 * @see DropTargetListener#dragOperationChanged
	 * @since 2.0 
	 */
	public static const int DROP_DEFAULT = 1 << 4;
	
	/**
	 * DragSource Event: the drop has successfully completed or has been terminated (such as hitting 
	 * the ESC key); perform cleanup such as removing data on a move operation (value is 2000).
	 */
	public static const int DragEnd		= 2000;
	
	/**
	 * DragSource Event: the data to be dropped is required from the drag source (value is 2001).
	 */
	public static const int DragSetData = 2001;
	
	/**
	 * DropTarget Event: the cursor has entered the drop target boundaries (value is 2002).
	 */
	public static const int DragEnter	= 2002;
	
	/**
	 * DropTarget Event: the cursor has left the drop target boundaries OR the drop
	 * operation has been cancelled (such as by hitting ECS) OR the drop is about to 
	 * happen (user has released the mous ebutotn over this target) (value is 2003).
	 */
	public static const int DragLeave	= 2003;
	
	/**
	 * DropTarget Event: the cursor is over the drop target (value is 2004).
	 */
	public static const int	DragOver	= 2004;
	
	/**
	 * DropTarget Event: the operation being performed has changed usually due to the user 
	 * changing the selected modifier keys while dragging (value is 2005).
	 */
	public static const int DragOperationChanged = 2005;
	
	/**
	 * DropTarget Event: the data has been dropped (value is 2006).
	 */
	public static const int	Drop = 2006;
	
	/**
	 * DropTarget Event: the drop target is given a last chance to modify the drop (value is 2007).
	 */
	public static const int	DropAccept	= 2007;
	
	/**
	 * DragSource Event: a drag is about to begin (value is 2008).
	 */
	public static const int	DragStart = 2008;

	/**
	 * DropTarget drag under effect: No effect is shown (value is 0).
	 */
	public static const int FEEDBACK_NONE = 0;
	
	/**
	 * DropTarget drag under effect: The item under the cursor is selected; applies to tables
	 * and trees (value is 1).
	 */
	public static const int FEEDBACK_SELECT = 1;
	
	/**
	 * DropTarget drag under effect: An insertion mark is shown before the item under the cursor; applies to 
	 * tables and trees (value is 2).
	 */
	public static const int FEEDBACK_INSERT_BEFORE = 2;
	
	/**
	 * DropTarget drag under effect:An insertion mark is shown after the item under the cursor; applies
	 * to tables and trees (value is 4).
	 */	
	public static const int FEEDBACK_INSERT_AFTER = 4;
	
	/**
	 * DropTarget drag under effect: The widget is scrolled up or down to allow the user to drop on items that 
	 * are not currently visible;  applies to tables and trees (value is 8).
	 */	
	public static const int FEEDBACK_SCROLL = 8;
	
	/**
	 * DropTarget drag under effect: The item currently under the cursor is expanded to allow the user to 
	 * select a drop target from a sub item; applies to trees (value is 16).
	 */	
	public static const int FEEDBACK_EXPAND = 16;
	
	/**
	 * Error code: drag source can not be initialized (value is 2000).
	 */
	public static const int ERROR_CANNOT_INIT_DRAG = 2000;
	
	/**
	 * Error code: drop target cannot be initialized (value is 2001).
	 */
	public static const int ERROR_CANNOT_INIT_DROP = 2001;
	
	/**
	 * Error code: Data can not be set on system clipboard (value is 2002).
	 */
	public static const int ERROR_CANNOT_SET_CLIPBOARD = 2002;
	
	/**
	 * Error code: Data does not have correct format for type (value is 2003).
	 * @since 3.1
	 */
	public static const int ERROR_INVALID_DATA = 2003;

	
	static char[] INIT_DRAG_MESSAGE =  "Cannot initialize Drag"; //$NON-NLS-1$
	static char[] INIT_DROP_MESSAGE =  "Cannot initialize Drop"; //$NON-NLS-1$
	static char[] CANNOT_SET_CLIPBOARD_MESSAGE =  "Cannot set data in clipboard"; //$NON-NLS-1$

/**
 * Throws an appropriate exception based on the passed in error code.
 *
 * @param code the DND error code
 */
//public static void error (String fileName, int line, int code) {
//	error (fileName, line, code, 0);
//}

/**
 * Throws an appropriate exception based on the passed in error code.
 * The <code>hresult</code> argument should be either 0, or the
 * platform specific error code.
 * <p>
 * In DND, errors are reported by throwing one of three exceptions:
 * <dl>
 * <dd>java.lang.IllegalArgumentException</dd>
 * <dt>thrown whenever one of the API methods is invoked with an illegal argument</dt>
 * <dd>org.eclipse.dwt.SWTException (extends java.lang.RuntimeException)</dd>
 * <dt>thrown whenever a recoverable error happens internally in DWT</dt>
 * <dd>org.eclipse.dwt.SWTError (extends java.lang.Error)</dd>
 * <dt>thrown whenever a <b>non-recoverable</b> error happens internally in DWT</dt>
 * </dl>
 * This method provides the logic which maps between error codes
 * and one of the above exceptions.
 * </p>
 *
 * @param code the DND error code.
 * @param hresult the platform specific error code.
 *
 * @see SWTError
 * @see SWTException
 * @see IllegalArgumentException
 */
//public static void error (TCHAR[] fileName, int line, int code, int hresult=0) {
//	return error(new String(fileName), line, code, hresult);
//}

public static void error (char[] fileName, int line, int code, int hresult=0) {
	Util.trace(("DND error at ") ~ fileName ~ ", line = %d", line);
	switch (code) {		
		/* OS Failure/Limit (fatal, may occur only on some platforms) */
		case DND.ERROR_CANNOT_INIT_DRAG:{
			char[] msg = (DND.INIT_DRAG_MESSAGE);
			if (hresult != 0) msg =  msg ~ " result = " ~ Converter.toHex(hresult)[]; //$NON-NLS-1$
			throw new Error(msg);
		}
		case DND.ERROR_CANNOT_INIT_DROP:{
			char[] msg = (DND.INIT_DROP_MESSAGE);
			if (hresult != 0) msg = msg ~ " result = " ~ Converter.toHex(hresult)[]; //$NON-NLS-1$
			throw new Error(msg);
		}
		case DND.ERROR_CANNOT_SET_CLIPBOARD:{
			char[] msg = (DND.CANNOT_SET_CLIPBOARD_MESSAGE);
			if (hresult != 0) msg = msg ~ " result = " ~ Converter.toHex(hresult)[]; //$NON-NLS-1$
			throw new Error(msg);
		}
		default : break;
	}
			
	/* Unknown/Undefined Error */
	DWT.error(__FILE__, __LINE__, code);
}

}
